<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // 原型我们会在面向对象中进行讨论

      // 什么是面向对象 ？ 是一种思想
      // 封装 继承 多态
      // js一切皆对象
      //   在 es5 的时候 js的面向对象由构造函数实现

      function Car(name) {
        this.name = name;
      }
      Car.prototype.say = () => {
        alert("dididi");
      };
      //car是一个构造函数 属性是私有的 方法是共享的（放在原型上就能共享）

      let falali = new Car("法拉利");
      falali.say();

      //   显式原型prototype的作用
      //  在一个构造函数的原型上扩充的方法能够被所有的实例所共享

      //   函数才有原型，因为在普通函数下不讨论，我们可以认为构造函数才有原型，原型的本质是一个对象，包含了被实例共享的方法以及一个constructor指向构造函数本身
      console.log(Car.prototype);

      // 隐式原型__proto__也是一个对象
      // 实例对象有__proto__ 跟实例的构造函数的prototype是一样的

      console.log(falali.__proto__);

      //   原型链值得是一个实例使用一个方法或者属性的时候，如果自己有就用自己的，如果没有就从__proto__里找，没有就再从__proto__找，知道找到object

      console.log(falali.toString());

      Array.prototype.fun1 = function () {
        alert("扩充的方法");
      };
      var arr1 = [1, 2, 3];
      arr1.fun1();
      //给数组原型上扩充一个方法 fun1 这个方法能被所有的实例共享
    </script>
  </body>
</html>
